home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland C++ V5.02 / GDIPRINT.PAK / PRINT.C < prev    next >
C/C++ Source or Header  |  1997-05-06  |  24KB  |  756 lines

  1. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  2. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  3. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright (C) 1993 - 1995  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //  MODULE: print.c
  9. //
  10. //  PURPOSE: Handle the application specific printing commands based on
  11. //    parameters gathered from the common printer dialog box.
  12. //
  13. //  FUNCTIONS:  
  14. //    CmdPrint      - Handles the File Print command.
  15. //    CmdPageSetup  - Handles the File PageSetup command.                
  16. //    CmdPrintSetup - Handles the File PrintSetup command. 
  17. //    Print         - Proceses printing request.
  18. //    PrintDIB      - Prints a DIB.
  19. //    CalculatePrintRect - Calculates the output rectangle on printer.
  20. //    AbortProc     - Processes messages for printer abort dialog box.
  21. //    AbortDlg      - Processes messages for application's AbortDlg dialog box.
  22. //    PageSetupProc - Displays dialog for page setup options.
  23. //
  24. //
  25. //  COMMENTS:
  26. //
  27. //  SPECIAL INSTRUCTIONS: N/A
  28. //
  29.  
  30.  
  31. #include <windows.h>            // required for all Windows applications 
  32. #include <windowsx.h> 
  33.            
  34. #include <string.h>
  35.            
  36. #include "globals.h"            // prototypes specific to this application
  37. #include "dibutil.h"
  38. #include "statbar.h"
  39. #include "print.h"
  40. #include "resource.h"
  41.  
  42. void Print(HWND, HDC, BOOL, BOOL, BOOL, BOOL, UINT, HGLOBAL);
  43. WORD PrintDIB(HDC, WORD, WORD, WORD, LPSTR);            
  44. BOOL CALLBACK AbortProc(HDC, int);
  45. LRESULT CALLBACK AbortDlg(HWND, UINT, WPARAM, LPARAM);
  46. void CalculatePrintRect(HDC, LPRECT, WORD, DWORD, DWORD);
  47. LRESULT CALLBACK PageSetupProc(HWND, UINT, WPARAM, LPARAM);
  48.               
  49. #define MAKEBOOL(i)      ((BOOL) !!(i))  
  50. #define PW_BESTFIT       1
  51. #define PW_SCALE         2
  52. #define PW_STRETCHTOPAGE 3
  53.  
  54. HANDLE hDevMode = NULL;
  55. HANDLE hDevNames = NULL;                     
  56. HWND hdlgAbort = NULL;   // Abort dialog hanlde
  57. BOOL fAbort = FALSE;     // Abort Flag     
  58. OPTIONSTRUCT PageSetupOptions;
  59.  
  60. // buffer for string resources
  61. char szBuffer[50];              // watch out for recursive use of this buffer!
  62.    
  63.   
  64. //  FUNCTION: CmdPrint(HWND, WORD, WORD, HWND)
  65. //
  66. //  PURPOSE:  Present the print dialog to the user and process the results.
  67. //
  68. //  PARAMETERS:
  69. //    hwnd     - The window.
  70. //    wCommand - WM_COMMAND
  71. //    wNotify  - Notification number (unused)
  72. //    hwndCtrl - NULL (unused)
  73. //
  74. //  RETURN VALUE:
  75. //    Always returns 0 - command handled.
  76. //
  77. //  COMMENTS:
  78. //   
  79. //
  80.  
  81. #pragma argsused
  82. LRESULT CmdPrint(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  83. {    
  84.     PRINTDLG pd = {0};
  85.     static DWORD Flags = PD_ALLPAGES | PD_SHOWHELP | PD_RETURNDC;    
  86.      static WORD nCopies = 1;
  87.      int cbWritten;
  88.    
  89.     cbWritten = LoadString(hInst, wCommand, szBuffer, sizeof(szBuffer)); 
  90.     if(cbWritten == 0)
  91.         lstrcpy(szBuffer, "Unknown Command");
  92.         
  93.     UpdateStatusBar(szBuffer, 0, 0);
  94.  
  95.     pd.lStructSize = sizeof(pd);
  96.     pd.hwndOwner   = hwnd;
  97.     pd.hDevMode    = hDevMode;
  98.     pd.hDevNames   = hDevNames;
  99.     pd.Flags       = Flags;
  100.     pd.nFromPage   = 1;
  101.     pd.nToPage     = 1;
  102.     pd.nMinPage    = 1;
  103.     pd.nMaxPage    = 1;
  104.     pd.nCopies     = nCopies;
  105.  
  106.     if (PrintDlg(&pd))
  107.     {       
  108.         Print(hwnd,
  109.               pd.hDC,
  110.               MAKEBOOL(pd.Flags & PD_PAGENUMS),
  111.               MAKEBOOL(pd.Flags & PD_SELECTION),
  112.               MAKEBOOL(pd.Flags & PD_COLLATE),
  113.               MAKEBOOL(pd.Flags & PD_PRINTTOFILE),             
  114.               pd.nCopies,
  115.               pd.hDevNames);
  116.               
  117.         hDevMode   = pd.hDevMode;
  118.         hDevNames  = pd.hDevNames;
  119.         Flags      = pd.Flags;       
  120.     }
  121.  
  122.     // once command is executed, set the statusbar text to original
  123.     UpdateStatusBar(SZDESCRIPTION, 0, 0);  
  124.     
  125.     return 0;
  126. }
  127.    
  128. //  FUNCTION: CmdPageSetup(HWND, WORD, WORD, HWND)
  129. //
  130. //  PURPOSE:  Present dialog with page setup options.
  131. //
  132. //  PARAMETERS:
  133. //    hwnd     - The window.
  134. //    wCommand - WM_COMMAND
  135. //    wNotify  - Notification number (unused)
  136. //    hwndCtrl - NULL (unused)
  137. //
  138. //  RETURN VALUE:
  139. //    Always returns 0 - command handled.
  140. //
  141. //  COMMENTS:
  142. //    The options provided allow the output to be scaled in
  143. //    different ways.
  144. //
  145.  
  146. #pragma argsused
  147. LRESULT CmdPageSetup(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  148. {
  149.      OPTIONSTRUCT Options;       // temp copy of options set in dialog
  150.     int iReturn;
  151.      int  cbWritten;
  152.  
  153.     cbWritten = LoadString(hInst, wCommand, szBuffer, sizeof(szBuffer)); 
  154.     if(cbWritten == 0)
  155.         lstrcpy(szBuffer, "Unknown Command");
  156.         
  157.     UpdateStatusBar(szBuffer, 0, 0);
  158.    
  159.     // get page setup options
  160.      iReturn = DialogBoxParam(hInst,
  161.                              "PageSetupBox", 
  162.                              hwnd, 
  163.                              (DLGPROC)PageSetupProc,
  164.                              (LPARAM)&Options);   
  165.                              
  166.     if (iReturn)
  167.         // user did not cancel dialog so save option settings
  168.         PageSetupOptions = Options;
  169.  
  170.     // once command is executed, set the statusbar text to original
  171.     UpdateStatusBar(SZDESCRIPTION, 0, 0);
  172.      return 0;
  173. }
  174.  
  175.    
  176. //  FUNCTION: CmdPrintSetup(HWND, WORD, WORD, HWND)
  177. //
  178. //  PURPOSE:  Present the print setup common dialog to the user.
  179. //
  180. //  PARAMETERS:
  181. //    hwnd     - The window.
  182. //    wCommand - WM_COMMAND
  183. //    wNotify  - Notification number (unused)
  184. //    hwndCtrl - NULL (unused)
  185. //
  186. //  RETURN VALUE:
  187. //    Always returns 0 - command handled.
  188. //
  189. //  COMMENTS:
  190. //    Assumes there is a resource string describing this command with the
  191. //    same ID as the command ID.  Loads the string and calls UpdateStatusBar
  192. //    to put the string into main pane of the status bar.
  193.  
  194.  
  195. #pragma argsused
  196. LRESULT CmdPrintSetup(HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
  197. {
  198.      PRINTDLG pd = {0};
  199.      int  cbWritten;
  200.  
  201.     cbWritten = LoadString(hInst, wCommand, szBuffer, sizeof(szBuffer)); 
  202.     if(cbWritten == 0)
  203.         lstrcpy(szBuffer, "Unknown Command");
  204.         
  205.     UpdateStatusBar(szBuffer, 0, 0);
  206.  
  207.     pd.lStructSize = sizeof(pd);
  208.     pd.hwndOwner   = hwnd;
  209.      pd.hDevMode    = hDevMode;
  210.     pd.hDevNames   = hDevNames;
  211.     pd.Flags = PD_SHOWHELP | PD_PRINTSETUP;
  212.  
  213.     if (PrintDlg(&pd))
  214.     {
  215.         hDevMode = pd.hDevMode;
  216.         hDevNames = pd.hDevNames;
  217.     }
  218.     
  219.     // once command is executed, set the statusbar text to original
  220.     UpdateStatusBar(SZDESCRIPTION, 0, 0);
  221.  
  222.     return 0;
  223. }
  224.  
  225.  
  226. //
  227. //  FUNCTION:
  228. //    Print(HWND, HDC, BOOL, BOOL, BOOL, BOOL, UINT, HGLOBAL)
  229. //
  230. //  PURPOSE: To print a DIB based on information from the
  231. //    common print dialog.
  232. //
  233. //
  234. //  PARAMETERS:
  235. //    hwnd - The window that the print message came from.
  236. //    hdc - The display context to print to.
  237. //    fPageNums - Print the page range specified by n[From|To]Page.
  238. //    fSelection - Print the current selection.
  239. //    fCollate - Print the pages in a collated order.
  240. //    fFile - Print to a file.
  241. //    uCopies - Number of copies to print
  242. //    hDevNames - Handle to DEVNAMES structure.
  243. //
  244. //  RETURN VALUE:
  245. //    None.
  246. //
  247. //  COMMENTS:
  248. //
  249. //
  250.  
  251. #pragma argsused
  252. VOID Print(HWND hwnd,
  253.            HDC  hdc,
  254.            BOOL fPageNums,
  255.            BOOL fSelection,
  256.            BOOL fCollate,
  257.            BOOL fFile,     
  258.            UINT uCopies,
  259.            HGLOBAL hDevNames)
  260. {
  261.      HCURSOR hcurSave;
  262.     DOCINFO di;
  263.     WORD wErrCode;   
  264.     UINT u;             // printing loop counter
  265.  
  266.     hcurSave = SetCursor(LoadCursor(NULL, IDC_WAIT));
  267.   
  268.     // Define the abort function
  269.     SetAbortProc(hdc, AbortProc);
  270.  
  271.     // Start the printing session
  272.     di.cbSize = sizeof(DOCINFO);
  273.      di.lpszDocName = "GDIPRINT";
  274.     di.lpszOutput = NULL;
  275.     if (StartDoc(hdc, &di) < 0)
  276.     {
  277.         // StartDoc failed so cancel print job
  278.                          
  279.         // remove hourglass cursor                   
  280.         SetCursor(hcurSave); 
  281.                                  
  282.         // tell the user        
  283.         MessageBox(hwnd, 
  284.                    "Unable to start print job", 
  285.                          SZAPPNAME,
  286.                    MB_OK | MB_ICONHAND); 
  287.                          
  288.         DeleteDC(hdc);
  289.         return;
  290.     }
  291.            
  292.     // clear the abort flag           
  293.     fAbort = FALSE; 
  294.  
  295.     // Create the AbortDlg dialog box (modeless)
  296.     hdlgAbort = CreateDialog(hInst, "AbortDlg", hwnd, (DLGPROC) AbortDlg);
  297.      if (!hdlgAbort)
  298.     {   
  299.         // failed to create abort dialog so cancel print job
  300.                     
  301.         // remove hourglass cursor                   
  302.         SetCursor(hcurSave); 
  303.         
  304.         // tell the user  
  305.         MessageBox(hwnd, 
  306.                    "NULL Abort window handle", 
  307.                    SZAPPNAME, 
  308.                    MB_OK | MB_ICONHAND);   
  309.  
  310.         DeleteDC(hdc);
  311.         return;
  312.     }
  313.  
  314.     // Now show Abort dialog
  315.     ShowWindow(hdlgAbort, SW_NORMAL);
  316.  
  317.     // Disable the main window to avoid reentrancy problems
  318.     EnableWindow(hwnd, FALSE); 
  319.     
  320.     // remove hourglass cursor
  321.      SetCursor(hcurSave);
  322.     
  323.     for (u = 0; u < uCopies; u++)
  324.     {
  325.         StartPage(hdc);
  326.     
  327.         wErrCode = PrintDIB(hdc, 
  328.                             (WORD)PageSetupOptions.iOption, 
  329.                             (WORD)PageSetupOptions.iXScale, 
  330.                             (WORD)PageSetupOptions.iYScale, 
  331.                             (LPSTR)(di.lpszDocName));
  332.         EndPage(hdc);    
  333.  
  334.         if (wErrCode)
  335.         {
  336.             DIBError(wErrCode);
  337.             break;
  338.         }
  339.     }
  340.     
  341.     EndDoc(hdc);
  342.            
  343.     EnableWindow(hwnd, TRUE);
  344.  
  345.      // Destroy the Abort dialog box
  346.     DestroyWindow(hdlgAbort);   
  347.     DeleteDC(hdc);
  348. }
  349.  
  350.                                                 
  351. //
  352. //  FUNCTION:
  353. //    PrintDIB(HDC, WORD, WORD, WORD, LPSTR)
  354. //
  355. //  PURPOSE: To print a DIB based on information from the
  356. //    common print dialog.
  357. //
  358. //
  359. //  PARAMETERS:
  360. //    hPrnDC - Printer device context
  361. //    fPrintOpt - Print Options
  362. //    wXScale - X Scaling factor
  363. //    wYScale - Y Scaling factor
  364. //    szJobName - Name of print job
  365. // 
  366. //
  367. //  RETURN VALUE:
  368. //    0 if successful, else an error code.
  369. //
  370. //  COMMENTS:
  371. //
  372. //
  373.  
  374. #pragma argsused
  375. WORD PrintDIB(HDC hPrnDC,
  376.               WORD fPrintOpt, 
  377.               WORD wXScale, 
  378.               WORD wYScale, 
  379.               LPSTR szJobName)
  380. {                                                   
  381.     LPBITMAPINFOHEADER lpDIBHdr; // Pointer to DIB header
  382.     RECT rcClip;                 // Rect structure used for banding  
  383.     RECT rcPrint;                // Rect which specifies the area on the printer
  384.                                  // (in printer coordinates) which we
  385.                                  // want the DIB to go to
  386.     RECT rcSrc, rcDest;          // rectangles for StretchDIBits;                                 
  387.      double dblXScaling;          // X scaling factor
  388.     double dblYScaling;          // Y scaling factor  
  389.     int iReturn;
  390.     WORD wErrorCode = 0;         // Error code to return
  391.           
  392.     lpDIBHdr = (LPBITMAPINFOHEADER)GlobalLock(hDIBInfo);
  393.     if (!lpDIBHdr) 
  394.         return ERR_LOCK;
  395.   
  396.     SetStretchBltMode(hPrnDC, COLORONCOLOR);
  397.      
  398.     // Determine rcPrint (printer area to print to) from the
  399.      // fPrintOpt.  Fill in rcPrint.left and .top from wXScale and
  400.     // wYScale just in case we use PW_SCALE (see the function
  401.     // CalculatePrintRect).  
  402.     rcPrint.left = wXScale;
  403.     rcPrint.top = wYScale;
  404.     CalculatePrintRect(hPrnDC, &rcPrint, fPrintOpt, lpDIBHdr->biWidth,
  405.                          lpDIBHdr->biHeight);
  406.     
  407.     // print the entire DIB     
  408.     rcClip = rcPrint;       
  409.  
  410.     dblXScaling = ((double)RECTWIDTH(&rcPrint)) / (double)lpDIBHdr->biWidth;
  411.      dblYScaling = ((double)RECTHEIGHT(&rcPrint)) / (double)lpDIBHdr->biHeight;
  412.  
  413.     // Create destination rectangle in device coordinates
  414.     IntersectRect(&rcDest, &rcPrint, &rcClip);
  415.     if (IsRectEmpty(&rcDest))
  416.     {
  417.         // nothing to print
  418.         wErrorCode = ERR_UNDEFINEDERROR;
  419.         goto ErrExit;
  420.     }
  421.     
  422.     // determine coordinates in DIB that will be printed    
  423.      rcSrc.left = (int)((rcDest.left - rcPrint.left) / dblXScaling + 0.5);
  424.     rcSrc.top  = (int)((rcDest.top - rcPrint.top) / dblYScaling + 0.5);
  425.     rcSrc.right = (int)((rcSrc.left + RECTWIDTH(&rcDest)) / dblXScaling + 0.5);
  426.     rcSrc.bottom = (int)((rcSrc.top + RECTHEIGHT(&rcDest)) / dblYScaling + 0.5);
  427.                         
  428.     iReturn = StretchDIBits(hPrnDC,                           // DestDC
  429.                             rcDest.left,                      // DestX
  430.                             rcDest.top,                       // DestY
  431.                             RECTWIDTH(&rcDest),               // DestWidth
  432.                             RECTHEIGHT(&rcDest),              // DestHeight
  433.                             rcSrc.left,                       // SrcX
  434.                             (int)(lpDIBHdr->biHeight) -       // SrcY
  435.                                      rcSrc.top - (RECTHEIGHT(&rcSrc)),
  436.                             RECTWIDTH(&rcSrc),                // SrcWidth
  437.                             RECTHEIGHT(&rcSrc),               // SrcHeight
  438.                             lpvBits,                          // lpBits
  439.                             (LPBITMAPINFO)lpDIBHdr,           // lpBitInfo
  440.                             DIB_RGB_COLORS,                   // wUsage
  441.                             SRCCOPY);                         // dwROP
  442.     
  443.     if (iReturn == 0)                       
  444.         // StretchDIBits() failed
  445.         wErrorCode = ERR_STRETCHDIBITS; 
  446.              
  447. ErrExit:
  448.     GlobalUnlock(hDIBInfo);                          
  449.  
  450.     return (wErrorCode);
  451. }
  452.  
  453.  
  454. //
  455. //  FUNCTION:
  456. //    CalculatePrintRect(HDC, LPRECT, WORD, DWORD, DWORD)   
  457. //
  458. //  PURPOSE: Returns area on printer where image will be printed.
  459. //
  460. //  PARAMETERS:
  461. //    hDC - Handle of printer device context.
  462. //    lprcPrint - address of rectangle filled in by this function.
  463. //    fPageSetup - page setup option flag.
  464. //    cxDIB - width of DIB in pixels
  465. //    cyDIB - height of DIB in pixels
  466. //
  467. //  RETURN VALUE:
  468. //    Depends on the message number.
  469. //
  470. //  COMMENTS:
  471. //    Given fPageSetup and a size of the DIB, return the area on the
  472. //    printer where the image should go (in printer coordinates).  If
  473. //    fPageSetup is PW_SCALE, then lprcPrint.left and .top should
  474. //    contain WORDs which specify the scaling factor for the X and
  475. //    Y directions, respecively.
  476. //
  477.  
  478. void CalculatePrintRect(HDC hDC, 
  479.                         LPRECT lprcPrint, 
  480.                         WORD fPageSetup, 
  481.                         DWORD cxDIB, 
  482.                         DWORD cyDIB)    
  483. {
  484.     int cxPage, cyPage, cxInch, cyInch;
  485.  
  486.     if (!hDC)
  487.         return;
  488.    
  489.     // Get some info from printer driver
  490.     cxPage = GetDeviceCaps(hDC, HORZRES);    // Width of printr page - pixels
  491.     cyPage = GetDeviceCaps(hDC, VERTRES);    // Height of printr page - pixels
  492.     cxInch = GetDeviceCaps(hDC, LOGPIXELSX); // Printer pixels per inch - X
  493.     cyInch = GetDeviceCaps(hDC, LOGPIXELSY); // Printer pixels per inch - Y
  494.     
  495.     switch (fPageSetup)
  496.     {
  497.         case PW_BESTFIT:
  498.             // Best Fit case -- create a rectangle which preserves
  499.             // the DIB's aspect ratio, and fills the page horizontally.
  500.             // The formula in the "->bottom" field below calculates the Y
  501.             // position of the printed bitmap, based on the size of the
  502.             // bitmap, the width of the page, and the relative size of
  503.             // a printed pixel (cyInch / cxInch).
  504.             
  505.             lprcPrint->top = 0;
  506.             lprcPrint->left = 0;
  507.             lprcPrint->bottom = 
  508.                 (int)(((double)cyDIB * cxPage * cyInch) / 
  509.                 ((double)cxDIB * cxInch));
  510.             lprcPrint->right = cxPage;   
  511.             
  512.             break;
  513.  
  514.         case PW_SCALE:
  515.         {               
  516.             // Scaling option -- lprcPrint's top/left contain
  517.             // multipliers to multiply the DIB's height/width by.
  518.     
  519.             int cxMult, cyMult;
  520.  
  521.             cxMult = lprcPrint->left;
  522.             cyMult = lprcPrint->top;
  523.             lprcPrint->top = 0;
  524.             lprcPrint->left = 0;
  525.             lprcPrint->bottom = (int)(cyDIB * cyMult);
  526.             lprcPrint->right = (int)(cxDIB * cxMult); 
  527.             
  528.             break;
  529.         }
  530.  
  531.         case PW_STRETCHTOPAGE:
  532.         default:          
  533.             // Stretch To Page case -- create a rectangle
  534.             // which covers the entire printing page (note that this
  535.             // is also the default).
  536.             
  537.             lprcPrint->top = 0;
  538.             lprcPrint->left = 0;
  539.             lprcPrint->bottom = cyPage;
  540.             lprcPrint->right = cxPage;
  541.                 
  542.             break;
  543.     }
  544. }
  545.                      
  546.                      
  547. //
  548. //  FUNCTION: AbortProc(HDC, int)
  549. //
  550. //  PURPOSE: Processes messages for the printer abort dialog box.
  551. //
  552. //  PARAMETERS:
  553. //    hdc - The printer device context.
  554. //    Code -  The error code (unused).
  555. //
  556. //  RETURN VALUE:
  557. //    Returns FALSE if the user has aborted, TRUE otherwise.
  558. //
  559. //  COMMENTS:
  560. //
  561. //
  562.  
  563. #pragma argsused
  564. BOOL CALLBACK AbortProc(HDC hdc, int Code)
  565. {
  566.      MSG msg;
  567.  
  568.     if (!hdlgAbort)              
  569.         // the abort dialog isn't up yet
  570.         return TRUE;
  571.  
  572.     // Process messages intended for the abort dialog box
  573.  
  574.     while (!fAbort && PeekMessage(&msg, NULL, 0, 0, TRUE))
  575.         if (!IsDialogMessage(hdlgAbort, &msg))
  576.         {
  577.             TranslateMessage(&msg);
  578.             DispatchMessage(&msg);
  579.           }
  580.  
  581.     // fAbort is TRUE (return is FALSE) if the user has aborted
  582.  
  583.     return !fAbort;
  584. }
  585.  
  586. //
  587. //  FUNCTION: AbortDlg(HWND, UINT, WPARAM, LPARAM)
  588. //
  589. //  PURPOSE: Processes messages for application's AbortDlg dialog box.
  590. //
  591. //  PARAMETERS:
  592. //    hdlg     - The dialog handle.
  593. //    uMessage - The message number.
  594. //    wparam   - Message specific data.
  595. //    lparam   - Message specific data.
  596. //
  597. //  RETURN VALUE:
  598. //    Depends on the message number.
  599. //
  600. //  COMMENTS:
  601. //      This dialog box is created while the program is printing, and allows
  602. //      the user to cancel the printing process.
  603. //
  604.  
  605. #pragma argsused
  606. LRESULT CALLBACK AbortDlg(HWND hdlg, UINT uMessage, 
  607.     WPARAM wparam, LPARAM lparam)
  608. {
  609.     switch(uMessage)
  610.     {
  611.         // watch for Cancel button, RETURN key, ESCAPE key, or SPACE BAR
  612.  
  613.         case WM_COMMAND:
  614.             return fAbort = TRUE;
  615.  
  616.         case WM_INITDIALOG:
  617.             // center the dialog over the application window
  618.             CenterWindow(hdlg, GetWindow(hdlg, GW_OWNER));
  619.     
  620.             // set the focus to the Cancel box of the dialog
  621.             SetFocus(GetDlgItem(hdlg, IDCANCEL));
  622.             
  623.             // identify the file being printed
  624.                 SetDlgItemText(hdlg, IDD_FILENAME, (LPCTSTR)szCurrentFile);
  625.             
  626.             return TRUE;
  627.     }
  628.  
  629.     return FALSE;
  630. }
  631.  
  632.  
  633. //
  634. //  FUNCTION: PageSetupProc(HWND, UINT, WPARAM, LPARAM)
  635. //
  636. //  PURPOSE: Provides page setup options.
  637. //
  638. //  PARAMETERS:
  639. //    hdlg     - The dialog handle.
  640. //    uMessage - The message number.
  641. //    wparam   - Message specific data.
  642. //    lparam   - Message specific data.
  643. //
  644. //  RETURN VALUE:
  645. //    Depends on the message number.
  646. //
  647. //  COMMENTS:
  648. //  
  649. //
  650.  
  651. LRESULT CALLBACK PageSetupProc(HWND hdlg,
  652.                                UINT uMessage, 
  653.                                WPARAM wparam,
  654.                                LPARAM lparam)
  655. {
  656.     static LPOPTIONSTRUCT lpOS;
  657.  
  658.     switch (uMessage)
  659.     {
  660.         case WM_INITDIALOG:
  661.         {      
  662.             // Center the dialog over the application window
  663.             CenterWindow(hdlg, GetWindow(hdlg, GW_OWNER));
  664.  
  665.             // Because DialogBoxParam() was used to invoke this dialog box,
  666.             // lparam contains a pointer to the OPTIONSTRUCT.
  667.             // Place user input in this structure before returning.
  668.             lpOS = (LPOPTIONSTRUCT)lparam;
  669.  
  670.             // Check the default button -- "BEST FIT"
  671.             CheckRadioButton(hdlg, IDD_BESTFIT, IDD_STRETCHTOPAGE, IDD_BESTFIT);
  672.  
  673.             // Gray out the stuff under "SCALE"
  674.             EnableWindow(GetDlgItem(hdlg, IDD_XAXIS), FALSE);
  675.             EnableWindow(GetDlgItem(hdlg, IDD_YAXIS), FALSE);
  676.             EnableWindow(GetDlgItem(hdlg, IDD_XTEXT), FALSE);
  677.             EnableWindow(GetDlgItem(hdlg, IDD_YTEXT), FALSE);
  678.             break;
  679.         }
  680.  
  681.         // Closing the Dialog should behave the same as Cancel
  682.  
  683.         case WM_CLOSE:        
  684.             PostMessage(hdlg, WM_COMMAND, IDCANCEL, 0L);
  685.             break;
  686.  
  687.         case WM_COMMAND:
  688.             switch (wparam)
  689.             {
  690.                 case IDD_BESTFIT:
  691.                 case IDD_STRETCHTOPAGE:
  692.                 case IDD_SCALE:
  693.  
  694.                     // Check the correct button
  695.                     CheckRadioButton(hdlg, IDD_BESTFIT, IDD_SCALE, wparam);
  696.  
  697.                     // And enable or disable the options under "Scale",
  698.                     // depending on whether or not the IDD_SCALE button
  699.                     // is checked
  700.                     EnableWindow(GetDlgItem(hdlg, IDD_XAXIS),
  701.                             (BOOL)(wparam == IDD_SCALE));
  702.                     EnableWindow(GetDlgItem(hdlg, IDD_YAXIS),
  703.                             (BOOL)(wparam == IDD_SCALE));
  704.                     EnableWindow(GetDlgItem(hdlg, IDD_XTEXT),
  705.                             (BOOL)(wparam == IDD_SCALE));
  706.                     EnableWindow(GetDlgItem(hdlg, IDD_YTEXT),
  707.                             (BOOL)(wparam == IDD_SCALE));
  708.                     break;
  709.  
  710.                 case IDOK:
  711.                 {
  712.                     char    szTmp[100];
  713.                     BOOL fTranslated;
  714.  
  715.                     // Save the user's selection into the OPTIONSTRUCT
  716.                     if (!lpOS)
  717.                     {
  718.                         EndDialog(hdlg, FALSE);
  719.                         break;
  720.                     }
  721.  
  722.                     if (IsDlgButtonChecked(hdlg, IDD_BESTFIT))
  723.                         lpOS->iOption = IDD_BESTFIT;
  724.  
  725.                     if (IsDlgButtonChecked(hdlg, IDD_STRETCHTOPAGE))
  726.                         lpOS->iOption = IDD_STRETCHTOPAGE;
  727.  
  728.                     if (IsDlgButtonChecked(hdlg, IDD_SCALE))
  729.                         lpOS->iOption = IDD_SCALE;   
  730.  
  731.                     if (GetDlgItemText(hdlg, IDD_XAXIS, (LPSTR)szTmp, sizeof(szTmp)))
  732.                         lpOS->iXScale = GetDlgItemInt(hdlg, IDD_XAXIS, &fTranslated, TRUE);
  733.  
  734.                     if (GetDlgItemText(hdlg, IDD_YAXIS, (LPSTR)szTmp, sizeof(szTmp)))
  735.                         lpOS->iYScale = GetDlgItemInt(hdlg, IDD_YAXIS, &fTranslated, TRUE);
  736.  
  737.                     EndDialog(hdlg, TRUE);
  738.                     break;
  739.                 }
  740.          
  741.  
  742.                 case IDCANCEL:
  743.                     EndDialog(hdlg, FALSE);
  744.                     break;
  745.  
  746.             } // End of WM_COMMAND
  747.                 
  748.  
  749.         default:
  750.             return FALSE;
  751.     }
  752.  
  753.     return TRUE;
  754. }
  755.  
  756.